package main

import (
	"fmt"
	"strconv"
)

/*
 * Bit positions for the ST1 and ST2 connectors
 */
const (
	pin1 = 1 << iota // pin1 对应位1 使用 iota 自动生成位掩码，表示不同的引脚位置 
	pin2             // pin2 对应位2 每个引脚对应一个特定的位值，便于后续的位运算
	pin3             // pin3 对应位4
	pin4             // pin4 对应位8
	pin5             // pin5 对应位16
	pin6             // pin6 对应位32
	pin7             // pin7 对应位64
	pin8             // pin8 对应位128
	pin9             // pin9 对应位256
	pin10            // pin10 对应位512
	_                // 空位，未使用
	_                // 空位，未使用
	_                // 空位，未使用
	pin14            // pin14 对应位8192
	pin15            // pin15 对应位16384
	pin16            // pin16 对应位32768
	pin17            // pin17 对应位65536
)

/*
 * Signal names on ST1 and ST2 connectors
 */
//定义了连接器ST1和ST2上的信号名称，并将它们映射到具体的引脚位置
//注意，有些信号共享相同的引脚（如 stPMinp 和 stCORRsrc 都在 pin14 上），这可能是出于设计上的复用考虑
const (
	stα        = pin1    // 信号 stα 对应 pin1
	stβ        = pin2    // 信号 stβ 对应 pin2
	stγ        = pin3    // 信号 stγ 对应 pin3
	stδ        = pin4    // 信号 stδ 对应 pin4
	stε        = pin5    // 信号 stε 对应 pin5
	stA        = pin6    // 信号 stA 对应 pin6
	stAS       = pin7    // 信号 stAS 对应 pin7
	stS        = pin8    // 信号 stS 对应 pin8
	stCLR      = pin9    // 信号 stCLR 对应 pin9
	stCORR     = pin10   // 信号 stCORR 对应 pin10
	stPMinp    = pin14   // 信号 stPMinp 对应 pin14
	stCORRsrc  = pin14   // 信号 stCORRsrc 对应 pin14
	stDEC10CAR = pin15   // 信号 stDEC10CAR 对应 pin15
	stDEC1inp  = pin15   // 信号 stDEC1inp 对应 pin15
	stSF0out   = pin16   // 信号 stSF0out 对应 pin16
	stDEC1sub  = pin16   // 信号 stDEC1sub 对应 pin16
	stSFSWinp  = pin17   // 信号 stSFSWinp 对应 pin17
	stSF10out  = pin17   // 信号 stSF10out 对应 pin17
)

type accumulator struct {
	α, β, γ, δ, ε, A, S chan pulse // 各个通道用于传输脉冲信号
	ctlterm             [20]chan pulse // 控制终端通道
	inff1, inff2        [12]bool      // 标志位数组
	opsw                [12]byte      // 操作开关数组
	clrsw               [12]bool      // 清除开关数组
	rptsw               [8]byte       // 重复开关数组
	sigfig              int           // 显著数字位数
	sc                  byte          // 小计
	val                 [10]byte      // 数值存储
	decff               [10]bool      // 十进制标志位
	sign                bool          // 符号位
	h50                 bool          // H50 标志位
	rep                 int           // 重复次数
	whichrp             bool          // 哪个重复
	change              chan int      // 变更通知通道
	lbuddy, rbuddy      int           // 左右伙伴索引
}

var units [20]accumulator

func accstat(unit int) string {
	var s string

	// 根据符号位设置初始字符串
	if units[unit].sign {
		s = "M " // 负数标记
	} else {
		s = "P " // 正数标记
	}

	// 添加数值部分（从最高位到最低位）
	for i := 9; i >= 0; i-- {
		s += fmt.Sprintf("%d", units[unit].val[i])
	}
	s += " "

	// 添加十进制标志位部分
	for i := 9; i >= 0; i-- {
		s += b2is(units[unit].decff[i])
	}
	s += fmt.Sprintf(" %d ", units[unit].rep)

	// 添加 inff1 标志位部分
	for _, f := range units[unit].inff1 {
		s += b2is(f)
	}

	return s
}

func accreset(unit int) {
	// 获取指定累加器单元的指针
	u := &units[unit]

	// 将各个信号通道设置为 nil
	u.α = nil
	u.β = nil
	u.γ = nil
	u.δ = nil
	u.ε = nil

	// 重置控制终端通道和各种标志位及开关
	for i := 0; i < 12; i++ {
		u.ctlterm[i] = nil           // 控制终端通道
		u.inff1[i] = false           // 标志位数组 inff1
		u.inff2[i] = false           // 标志位数组 inff2
		u.opsw[i] = 0                // 操作开关数组 opsw
		u.clrsw[i] = false           // 清除开关数组 clrsw
	}

	// 重置重复开关数组
	for i := 0; i < 8; i++ {
		u.rptsw[i] = 0               // 重复开关数组 rptsw
	}

	// 重置其他字段
	u.sigfig = 10                  // 显著数字位数设为10
	u.sc = 0                       // 小计值设为0
	u.h50 = false                  // H50 标志位设为 false
	u.rep = 0                      // 重复次数设为0
	u.whichrp = false              // 哪个重复标志位设为 false
	u.lbuddy = unit                // 左伙伴索引设为当前单元索引
	u.rbuddy = unit                // 右伙伴索引设为当前单元索引

	// 调用 accclear 函数清除数值部分
	accclear(unit)

	// 发送变更通知
	u.change <- 1
}

func accclear(acc int) {
	// 遍历 val 数组，将其所有元素设为 0
	for i := 0; i < 10; i++ {
		units[acc].val[i] = 0
		units[acc].decff[i] = false
	}

	// 如果显著数字位数小于10，则在相应位置设置值为5
	if units[acc].sigfig < 10 {
		units[acc].val[9-units[acc].sigfig] = 5
	}

	// 重置符号位
	units[acc].sign = false
}

func accinterconnect(p1 []string, p2 []string) {
	unit1, _ := strconv.Atoi(p1[0][1:]) // 从 p1[0] 中提取第一个累加器单元编号并转换为整数
	unit2 := -1                         // 初始化第二个累加器单元编号为 -1

	// 如果 p2 长度大于1且 p2[0] 以 'a' 开头，则从 p2[0] 中提取第二个累加器单元编号并转换为整数
	if len(p2) > 1 && p2[0][0] == 'a' {
		unit2, _ = strconv.Atoi(p2[0][1:])
	}

	// 根据不同的命令进行相应的操作
	switch {
	case p2[0] == "m" && p2[1] == "l":
		units[unit1-1].lbuddy = -1 // 设置 unit1 的左伙伴为 -1（特殊标记）

	case p2[0] == "m" && p2[1] == "r":
		units[unit1-1].lbuddy = -2 // 设置 unit1 的左伙伴为 -2（特殊标记）

	case p2[0] == "d" && p2[1] == "sv":
		units[unit1-1].lbuddy = -3 // 设置 unit1 的左伙伴为 -3（特殊标记）

	case p2[0] == "d" && p2[1] == "su2q":
		units[unit1-1].lbuddy = -4 // 设置 unit1 的左伙伴为 -4（特殊标记）

	case p2[0] == "d" && p2[1] == "su2s":
		units[unit1-1].lbuddy = -5 // 设置 unit1 的左伙伴为 -5（特殊标记）

	case p2[0] == "d" && p2[1] == "su3":
		units[unit1-1].lbuddy = -6 // 设置 unit1 的左伙伴为 -6（特殊标记）

	case p1[1] == "st1" || p1[1] == "il1":
		if unit2 != -1 && unit1 != unit2 {
			units[unit1-1].lbuddy = unit2 - 1 // 设置 unit1 的左伙伴为 unit2
			units[unit2-1].rbuddy = unit1 - 1 // 设置 unit2 的右伙伴为 unit1
		}

	case p1[1] == "st2" || p1[1] == "ir1":
		if unit2 != -1 && unit1 != unit2 {
			units[unit1-1].rbuddy = unit2 - 1 // 设置 unit1 的右伙伴为 unit2
			units[unit2-1].lbuddy = unit1 - 1 // 设置 unit2 的左伙伴为 unit1
		}

	case p1[1] == "su1" || p1[1] == "il2":
		if unit2 != -1 && unit1 != unit2 {
			units[unit1-1].lbuddy = unit2 - 1 // 设置 unit1 的左伙伴为 unit2
			units[unit2].rbuddy = unit1 - 1   // 设置 unit2 的右伙伴为 unit1
		}

	case p1[1] == "su2" || p1[1] == "ir2":
		if unit2 != -1 && unit1 != unit2 {
			units[unit1-1].rbuddy = unit2 - 1 // 设置 unit1 的右伙伴为 unit2
			units[unit2-1].lbuddy = unit1 - 1 // 设置 unit2 的左伙伴为 unit1
		}
	}

	// 如果 unit2 不是 -1 且 unit1 和 unit2 不相同，则发送变更通知
	if unit2 != -1 && unit1 != unit2 {
		units[unit1-1].change <- 1
		units[unit2-1].change <- 1
	}
}

func accplug(unit int, jack string, ch chan pulse) {
	// 定义所有可用的插孔名称
	jacks := [20]string{"1i", "2i", "3i", "4i", "5i", "5o", "6i", "6o", "7i", "7o",
		"8i", "8o", "9i", "9o", "10i", "10o", "11i", "11o", "12i", "12o"}

	// 根据不同的插孔名称进行相应的操作
	switch {
	case jack == "α" || jack == "a" || jack == "alpha":
		units[unit].α = ch // 将通道 ch 连接到 α 信号

	case jack == "β" || jack == "b" || jack == "beta":
		units[unit].β = ch // 将通道 ch 连接到 β 信号

	case jack == "γ" || jack == "g" || jack == "gamma":
		units[unit].γ = ch // 将通道 ch 连接到 γ 信号

	case jack == "δ" || jack == "d" || jack == "delta":
		units[unit].δ = ch // 将通道 ch 连接到 δ 信号

	case jack == "ε" || jack == "e" || jack == "epsilon":
		units[unit].ε = ch // 将通道 ch 连接到 ε 信号

	case jack == "A":
		units[unit].A = ch // 将通道 ch 连接到 A 信号

	case jack == "S":
		units[unit].S = ch // 将通道 ch 连接到 S 信号

	case jack[0] == 'I': // 处理以 'I' 开头的插孔名称
		// 这里没有具体的实现，可能需要根据实际情况添加逻辑

	default:
		// 如果插孔名称不在预定义列表中，则尝试匹配控制终端插孔
		foundjack := false
		for i, j := range jacks {
			if j == jack {
				units[unit].ctlterm[i] = ch // 将通道 ch 连接到对应的控制终端插孔
				foundjack = true
				break
			}
		}
		if !foundjack {
			fmt.Println("Invalid jack:", jack, "on accumulator", unit+1)
		}
	}

	// 发送变更通知
	units[unit].change <- 1
}

func accctl(unit int, ch chan [2]string) {
	// 初始化左右伙伴索引为当前单元
	units[unit].lbuddy = unit
	units[unit].rbuddy = unit

	// 无限循环等待并处理控制指令
	for {
		ctl := <-ch // 从通道中接收控制指令
		prog, _ := strconv.Atoi(ctl[0][2:]) // 提取程序编号并转换为整数
		prog-- // 程序编号从1开始，所以减1调整为从0开始

		switch ctl[0][:2] { // 根据控制指令的前两个字符进行分类处理
		case "op":
			// 处理操作开关设置
			switch ctl[1] {
			case "α", "a", "alpha":
				units[unit].opsw[prog] = 0
			case "β", "b", "beta":
				units[unit].opsw[prog] = 1
			case "γ", "g", "gamma":
				units[unit].opsw[prog] = 2
			case "δ", "d", "delta":
				units[unit].opsw[prog] = 3
			case "ε", "e", "epsilon":
				units[unit].opsw[prog] = 4
			case "0":
				units[unit].opsw[prog] = 5
			case "A":
				units[unit].opsw[prog] = 6
			case "AS":
				units[unit].opsw[prog] = 7
			case "S":
				units[unit].opsw[prog] = 8
			default:
				fmt.Println("Invalid operation code:", ctl[1], "on unit",
					unit+1, "program", prog+1)
			}

		case "cc":
			// 处理清除/纠正设置
			switch ctl[1] {
			case "0":
				units[unit].clrsw[prog] = false
			case "C", "c":
				units[unit].clrsw[prog] = true
			default:
				fmt.Println("Invalid clear/correct setting:", ctl[1], "on unit",
					unit+1, "program", prog+1)
			}

		case "rp":
			// 处理重复次数设置
			rpt, err := strconv.Atoi(ctl[1])
			if err == nil {
				units[unit].rptsw[prog-4] = byte(rpt - 1)
			} else {
				fmt.Println("Invalid repeat count:", ctl[1], "on unit",
					unit+1, "program", prog+1)
			}

		case "sf":
			// 处理显著数字位数设置
			n, _ := strconv.Atoi(ctl[1])
			units[unit].sigfig = n

		case "sc":
			// 处理选择性清除设置
			switch ctl[1] {
			case "0":
				units[unit].sc = 0
			case "SC", "sc":
				units[unit].sc = 1
			default:
				fmt.Println("Invalid selective clear setting:", ctl[1],
					"on unit", unit+1)
			}
		}
	}
}

/*
 * Implement the PX-5-109 terminator and PX-5-110
 * and PX-5-121 interconnect cables
 */

func su1(unit int) int {
	u := &units[unit] // 获取指定累加器单元的指针
	x := 0            // 初始化状态值为0

	// 如果右伙伴存在且不等于当前单元，则递归调用 su1 处理右伙伴
	if u.rbuddy >= 0 && u.rbuddy != unit {
		x = su1(u.rbuddy)
	}

	// 遍历标志位数组 inff1 和 inff2
	for i := 0; i < 12; i++ {
		if u.inff1[i] || u.inff2[i] { // 如果任一标志位为 true
			switch u.opsw[i] { // 根据操作开关的值进行处理
			case 0:
				x |= stα    // 设置状态值中的 α 位
			case 1:
				x |= stβ    // 设置状态值中的 β 位
			case 2:
				x |= stγ    // 设置状态值中的 γ 位
			case 3:
				x |= stδ    // 设置状态值中的 δ 位
			case 4:
				x |= stε    // 设置状态值中的 ε 位
			case 6:
				x |= stA    // 设置状态值中的 A 位
			case 7:
				x |= stAS   // 设置状态值中的 AS 位
			case 8:
				x |= stS    // 设置状态值中的 S 位
			}

			// 如果清除开关为 true
			if u.clrsw[i] {
				if u.opsw[i] >= 5 { // 如果操作开关大于等于5
					// 检查是否满足重复次数条件
					if i < 4 || u.rep == int(u.rptsw[i-4]) {
						x |= stCLR // 设置状态值中的 CLR 位
					}
				} else {
					x |= stCORR // 否则设置状态值中的 CORR 位
				}
			}
		}
	}

	return x // 返回最终的状态值
}

func st1(unit int) int {
	u := &units[unit] // 获取指定累加器单元的指针
	x := 0            // 初始化状态值为0

	// 根据 lbuddy 的值进行不同的处理
	if u.lbuddy == unit {
		// 左伙伴是自身
		x = su1(unit)
	} else if u.lbuddy == -1 {
		// 特殊标记 -1
		x = su1(unit)
		if Multl { // 如果 Multl 为 true
			x |= stα // 设置状态值中的 α 位
		}
	} else if u.lbuddy == -2 {
		// 特殊标记 -2
		x = su1(unit)
		if Multr { // 如果 Multr 为 true
			x |= stα // 设置状态值中的 α 位
		}
	} else if u.lbuddy == -3 {
		// 特殊标记 -3
		x = su1(unit)
		x |= divsr.sv // 设置状态值中的 sv 位
	} else if u.lbuddy == -4 {
		// 特殊标记 -4
		x = su1(unit)
		/* Wiring for PX-5-134 for quotient */
		x |= divsr.su2 & stα                   // 设置状态值中的 α 位
		x |= (divsr.su2 & su2qA) << 2          // 设置状态值中的 A 位并左移2位
		x |= (divsr.su2 & su2qS) << 3          // 设置状态值中的 S 位并左移3位
		x |= (divsr.su2 & su2qCLR) << 3        // 设置状态值中的 CLR 位并左移3位
	} else if u.lbuddy == -5 {
		// 特殊标记 -5
		x = su1(unit)
		/* Wiring for PX-5-135 for shift */
		x |= (divsr.su2 & su2sα) >> 1          // 设置状态值中的 α 位并右移1位
		x |= (divsr.su2 & su2sA) << 3          // 设置状态值中的 A 位并左移3位
		x |= (divsr.su2 & su2sCLR) << 2        // 设置状态值中的 CLR 位并左移2位
	} else if u.lbuddy == -6 {
		// 特殊标记 -6
		x = su1(unit)
		/* Wiring for PX-5-136 for denominator */
		x |= divsr.su3 & (stα | stβ | stγ)     // 设置状态值中的 α, β, γ 位
		x |= (divsr.su3 & su3A) << 2           // 设置状态值中的 A 位并左移2位
		x |= (divsr.su3 & su3S) << 3           // 设置状态值中的 S 位并左移3位
		x |= (divsr.su3 & su3CLR) << 3         // 设置状态值中的 CLR 位并左移3位
	} else {
		// 处理正常连接的左伙伴
		x = st2(u.lbuddy) & 0x1c3ff // 调用 st2 函数并进行位掩码操作
	}

	return x // 返回最终的状态值
}

func st2(unit int) int {
	// u := &units[unit]  // 这行代码被注释掉了，可能是为了备用或调试目的
	x := st1(unit) & 0x03ff  // 调用 st1 函数并进行位掩码操作

	return x  // 返回最终的状态值
}

func accrecv(unit, dat int) {
	u := &units[unit] // 获取指定累加器单元的指针

	// 遍历 val 数组中的每个元素
	for i := 0; i < 10; i++ {
		if dat&1 == 1 { // 检查 dat 的最低位是否为 1
			u.val[i]++ // 将对应的 val 元素加 1

			// 如果 val[i] 达到或超过 10，则设置 decff 标志并进行进位处理
			if u.val[i] >= 10 {
				u.decff[i] = true
				u.val[i] -= 10
			}
		}
		dat >>= 1 // 右移 dat，处理下一位
	}

	// 处理 dat 的最高位（第 10 位）
	if dat&1 == 1 {
		u.sign = !u.sign // 翻转符号位
	}
}

func docpp(u *accumulator, resp chan int, cyc int) {
	// 重置前四个 inff2 标志位
	for i := 0; i < 4; i++ {
		if u.inff2[i] {
			u.inff2[i] = false
		}
	}

	// 如果 h50 标志为 true
	if u.h50 {
		u.rep++ // 增加重复计数

		rstrep := false // 标记是否需要重置重复计数

		// 遍历第 4 到第 11 的 inff2 标志位
		for i := 4; i < 12; i++ {
			if u.inff2[i] && u.rep == int(u.rptsw[i-4])+1 {
				u.inff2[i] = false // 重置当前标志位
				rstrep = true      // 设置需要重置重复计数的标记

				t := (i-4)*2 + 5 // 计算对应的控制终端索引

				// 如果对应的控制终端不为空，则发送脉冲并等待响应
				if u.ctlterm[t] != nil {
					u.ctlterm[t] <- pulse{1, resp}
					<-resp // 等待响应
				}
			}
		}

		// 如果需要重置重复计数
		if rstrep {
			u.rep = 0    // 重置重复计数
			u.h50 = false // 关闭 h50 标志
		}
	}
}

func ripple(unit int) {
	u := &units[unit] // 获取指定累加器单元的指针

	// 处理前9个位置的进位
	for i := 0; i < 9; i++ {
		if u.decff[i] { // 如果当前位置有进位标志
			u.val[i+1]++ // 将下一位的值加1

			// 如果下一位的值达到10，则设置为0并设置下一位的进位标志
			if u.val[i+1] == 10 {
				u.val[i+1] = 0
				u.decff[i+1] = true
			}
		}
	}

	// 处理第10个位置的进位
	if u.lbuddy < 0 || u.lbuddy == unit { // 如果没有左伙伴或左伙伴是自身
		if u.decff[9] { // 如果第10位有进位标志
			/*
			 * Connection PX-5-121 pins 14, 15
			 */
			u.sign = !u.sign // 翻转符号位
		}
	} else { // 如果有左伙伴
		/*
		 * PX-5-110, pin 15 straight through
		 */
		if u.decff[9] { // 如果第10位有进位标志
			units[u.lbuddy].val[0]++ // 将左伙伴的第一个位置的值加1

			// 如果左伙伴的第一个位置的值达到10，则设置为0并设置其进位标志
			if units[u.lbuddy].val[0] == 10 {
				units[u.lbuddy].val[0] = 0
				units[u.lbuddy].decff[0] = true
			}
		}
		ripple(u.lbuddy) // 递归调用 ripple 处理左伙伴
	}
}

func doccg(u *accumulator, unit int, resp chan int) {
	curprog := st1(unit) // 获取当前程序状态值
	u.whichrp = false    // 重置 whichrp 标志

	// 检查当前程序状态是否包含非零操作
	if curprog&0x1f != 0 {
		if u.rbuddy == unit { // 如果右伙伴是自身
			ripple(unit) // 调用 ripple 函数进行进位传播
		}
	} else if (curprog & stCLR) != 0 { // 如果当前程序状态包含清除标志
		// 清除 val 数组中的所有值
		for i := 0; i < 10; i++ {
			u.val[i] = byte(0)
		}

		// 根据 sigfig 设置特定位置的值为 5
		if u.sigfig < 10 {
			u.val[9-u.sigfig] = 5
		}

		// 重置符号位
		u.sign = false
	}
}

func dorp(u *accumulator) {
	// 检查是否已经执行过此操作
	if !u.whichrp {
		/*
		 * Ugly hack to avoid races.  Effectively this is
		 * a coarse approximation to the "slow buffer
		 * output" described in 1.2.9 of the Technical
		 * Manual Part 2.
		 */
		// 遍历 inff1 数组，并将相应的标志转移到 inff2
		for i := 0; i < 12; i++ {
			if u.inff1[i] { // 如果当前标志位为 true
				u.inff2[i] = true // 将标志位转移到 inff2
				u.inff1[i] = false // 清除 inff1 中的标志位
				if i >= 4 { // 如果索引大于等于 4
					u.h50 = true // 设置 h50 标志
				}
			}
		}

		// 重置 decff 数组中的所有标志位
		for i := 0; i < 10; i++ {
			u.decff[i] = false
		}

		// 标记此操作已完成
		u.whichrp = true
	}
}

func dotenp(u *accumulator, unit int) {
	// 获取当前程序状态值
	curprog := st1(unit)

	// 检查当前程序状态是否包含 stA、stAS 或 stS 标志
	if curprog&(stA|stAS|stS) != 0 {
		// 遍历 val 数组中的每个元素
		for i := 0; i < 10; i++ {
			u.val[i]++ // 将对应的 val 元素加 1

			// 如果 val[i] 达到 10，则设置 decff 标志并进行进位处理
			if u.val[i] == 10 {
				u.val[i] = 0 // 将该位置的值重置为 0
				u.decff[i] = true // 设置进位标志
			}
		}
	}
}

func doninep(u *accumulator, unit int, resp chan int) {
	// 获取当前程序状态值
	curprog := st1(unit)

	// 如果当前程序状态包含 stA 或 stAS 标志
	if curprog&(stA|stAS) != 0 {
		if u.A != nil { // 检查 A 通道是否存在
			n := 0
			// 遍历 decff 数组中的每个元素
			for i := 0; i < 10; i++ {
				if u.decff[i] { // 如果当前进位标志为 true
					n |= 1 << uint(i) // 设置对应的位
				}
			}
			// 如果符号位为 true，则设置第 10 位
			if u.sign {
				n |= 1 << 10
			}
			// 如果 n 不为 0，则发送脉冲信号并等待响应
			if n != 0 {
				u.A <- pulse{n, resp}
				<-resp // 等待响应
			}
		}
	}

	// 如果当前程序状态包含 stAS 或 stS 标志
	if curprog&(stAS|stS) != 0 {
		if u.S != nil { // 检查 S 通道是否存在
			n := 0
			// 遍历 decff 数组中的每个元素
			for i := 0; i < 10; i++ {
				if !u.decff[i] { // 如果当前进位标志为 false
					n |= 1 << uint(i) // 设置对应的位
				}
			}
			// 如果符号位为 false，则设置第 10 位
			if !u.sign {
				n |= 1 << 10
			}
			// 如果 n 不为 0，则发送脉冲信号并等待响应
			if n != 0 {
				u.S <- pulse{n, resp}
				<-resp // 等待响应
			}
		}
	}
}

func doonepp(u *accumulator, unit int, resp chan int) {
	// 获取当前程序状态值
	curprog := st1(unit)

	// 如果当前程序状态包含 stCORR 标志
	if curprog&stCORR != 0 {
		/*
		 * Connection of PX-5-109 pins 14, 15
		 */
		if u.rbuddy == unit { // 如果右伙伴是自身
			u.val[0]++ // 将 val 数组的第一个元素加 1

			// 如果 val[0] 大于 9，则进行进位处理
			if u.val[0] > 9 {
				u.val[0] = 0 // 将该位置的值重置为 0
				u.decff[0] = true // 设置进位标志
			}
		}
	}

	// 如果当前程序状态包含 stAS 或 stS 标志，并且 S 通道存在
	if curprog&(stAS|stS) != 0 && u.S != nil {
		// 检查多种条件组合
		if ((u.lbuddy < 0 || u.lbuddy == unit) && u.rbuddy == unit && u.sigfig > 0) ||
			(u.rbuddy != unit && u.sigfig < 10) ||
			(u.lbuddy != unit && u.lbuddy >= 0 && units[u.lbuddy].sigfig == 10 && u.sigfig > 0) ||
			(u.rbuddy != unit && u.sigfig == 10 && units[u.rbuddy].sigfig == 0) {

			// 发送脉冲信号并等待响应
			u.S <- pulse{1 << uint(10-u.sigfig), resp}
			<-resp // 等待响应
		}
	}
}

func accunit(unit int, cyctrunk chan pulse) {
	u := &units[unit] // 获取指定累加器单元的指针

	// 初始化累加器单元的一些状态
	u.change = make(chan int)
	u.sigfig = 10
	u.lbuddy = unit
	u.rbuddy = unit

	// 启动一个 goroutine 运行辅助函数 accunit2
	go accunit2(unit)

	// 创建响应通道
	resp := make(chan int)

	// 无限循环监听并处理来自 cyctrunk 通道的脉冲信号
	for {
		p := <-cyctrunk // 接收脉冲信号
		cyc := p.val    // 获取脉冲信号中的周期值

		// 根据周期值执行不同的操作
		switch {
		case cyc&Cpp != 0:
			docpp(u, resp, cyc) // 处理 Cpp 操作
		case cyc&Ccg != 0:
			doccg(u, unit, resp) // 处理 Ccg 操作
		case cyc&Scg != 0:
			if u.sc == 1 {
				accclear(unit) // 如果 sc 为 1，则执行清除操作
			}
		case cyc&Rp != 0:
			dorp(u) // 处理 Rp 操作
		case cyc&Tenp != 0:
			dotenp(u, unit) // 处理 Tenp 操作
		case cyc&Ninep != 0:
			doninep(u, unit, resp) // 处理 Ninep 操作
		case cyc&Onepp != 0:
			doonepp(u, unit, resp) // 处理 Onepp 操作
		}

		// 如果脉冲信号包含响应通道，则发送响应
		if p.resp != nil {
			p.resp <- 1
		}
	}
}

func accunit2(unit int) {
	var dat, prog pulse // 定义两个脉冲变量，用于接收数据和程序信号

	u := &units[unit] // 获取指定累加器单元的指针

	for {
		select {
		case <-u.change:
			// 处理 change 通道的事件（当前未实现具体逻辑）
		case dat = <-u.α: // 监听 α 通道
			if st1(unit)&stα != 0 { // 检查当前状态是否包含 stα 标志
				accrecv(unit, dat.val) // 调用 accrecv 处理接收到的数据
			}
			if dat.resp != nil { // 如果响应通道不为空，则发送响应
				dat.resp <- 1
			}
		case dat = <-u.β: // 监听 β 通道
			if st1(unit)&stβ != 0 { // 检查当前状态是否包含 stβ 标志
				accrecv(unit, dat.val) // 调用 accrecv 处理接收到的数据
			}
			if dat.resp != nil { // 如果响应通道不为空，则发送响应
				dat.resp <- 1
			}
		case dat = <-u.γ: // 监听 γ 通道
			if st1(unit)&stγ != 0 { // 检查当前状态是否包含 stγ 标志
				accrecv(unit, dat.val) // 调用 accrecv 处理接收到的数据
			}
			if dat.resp != nil { // 如果响应通道不为空，则发送响应
				dat.resp <- 1
			}
		case dat = <-u.δ: // 监听 δ 通道
			if st1(unit)&stδ != 0 { // 检查当前状态是否包含 stδ 标志
				accrecv(unit, dat.val) // 调用 accrecv 处理接收到的数据
			}
			if dat.resp != nil { // 如果响应通道不为空，则发送响应
				dat.resp <- 1
			}
		case dat = <-u.ε: // 监听 ε 通道
			if st1(unit)&stε != 0 { // 检查当前状态是否包含 stε 标志
				accrecv(unit, dat.val) // 调用 accrecv 处理接收到的数据
			}
			if dat.resp != nil { // 如果响应通道不为空，则发送响应
				dat.resp <- 1
			}
		case prog = <-u.ctlterm[0]: // 监听 ctlterm[0] 控制终端
			if prog.val == 1 { // 如果接收到的值为 1
				u.inff1[0] = true // 设置 inff1[0] 标志位
			}
			if prog.resp != nil { // 如果响应通道不为空，则发送响应
				prog.resp <- 1
			}
		case prog = <-u.ctlterm[1]: // 监听 ctlterm[1] 控制终端
			if prog.val == 1 { // 如果接收到的值为 1
				u.inff1[1] = true // 设置 inff1[1] 标志位
			}
			if prog.resp != nil { // 如果响应通道不为空，则发送响应
				prog.resp <- 1
			}
		// 类似地处理其他 ctlterm 控制终端
		case prog = <-u.ctlterm[2]:
			if prog.val == 1 {
				u.inff1[2] = true
			}
			if prog.resp != nil {
				prog.resp <- 1
			}
		case prog = <-u.ctlterm[3]:
			if prog.val == 1 {
				u.inff1[3] = true
			}
			if prog.resp != nil {
				prog.resp <- 1
			}
		case prog = <-u.ctlterm[4]:
			if prog.val == 1 {
				u.inff1[4] = true
			}
			if prog.resp != nil {
				prog.resp <- 1
			}
		case prog = <-u.ctlterm[6]:
			if prog.val == 1 {
				u.inff1[5] = true
			}
			if prog.resp != nil {
				prog.resp <- 1
			}
		case prog = <-u.ctlterm[8]:
			if prog.val == 1 {
				u.inff1[6] = true
			}
			if prog.resp != nil {
				prog.resp <- 1
			}
		case prog = <-u.ctlterm[10]:
			if prog.val == 1 {
				u.inff1[7] = true
			}
			if prog.resp != nil {
				prog.resp <- 1
			}
		case prog = <-u.ctlterm[12]:
			if prog.val == 1 {
				u.inff1[8] = true
			}
			if prog.resp != nil {
				prog.resp <- 1
			}
		case prog = <-u.ctlterm[14]:
			if prog.val == 1 {
				u.inff1[9] = true
			}
			if prog.resp != nil {
				prog.resp <- 1
			}
		case prog = <-u.ctlterm[16]:
			if prog.val == 1 {
				u.inff1[10] = true
			}
			if prog.resp != nil {
				prog.resp <- 1
			}
		case prog = <-u.ctlterm[18]:
			if prog.val == 1 {
				u.inff1[11] = true
			}
			if prog.resp != nil {
				prog.resp <- 1
			}
		}
	}
}
